﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Media;

namespace FileRenamer
{

	public class ListOfFiles : List<FileToRename>, IComparer<FileToRename>
	{
		#region enums
		public enum Order { Asc, Desc }

		public enum FileCompareOptions
		{
			FileName, LastWriteTime, LastAccessTime, CreateDate, Length, Extension
		}
		#endregion

		#region Session struct
		public struct SessionData
		{
			public String Mode;
			public String RootPath;
			public List<String> OnlyExt;
			public List<String> ExcludeExt;
			public Order Order;
			public FileCompareOptions SortBy;
			public string Regex, RegexReplace;
			public string Expression;
			public bool Recursive;
			public string SearchPatturn;
		}
		#endregion

		public SessionData Session;

		public ListOfFiles()
		{
		}
		
		public ListOfFiles(List<FileInfo> originalFiles)
			: base()
		{
			foreach (FileInfo f in originalFiles) Add(f);
		}

		/// <summary>
		/// Hide the regular Add method.
		/// </summary>
		/// <param name="file"></param>
		private new void Add(FileToRename file)
		{
			base.Add(file);
		}
		public void Add(FileInfo file)
		{
			if ((file.Attributes & FileAttributes.System) != FileAttributes.System &&
				(file.Attributes & FileAttributes.Hidden) != FileAttributes.Hidden && !file.DirectoryName.Contains(@"\$RECYCLE.BIN\"))
			{
				if ((file.Attributes & FileAttributes.System) != FileAttributes.System)
				{
					Add(new FileToRename(file));
				}
			}
		}

		public void RemoveFile(String fileName)
		{
			for (int i = 0; i < this.Count; i++)
				if (this[i].FileName.FullName == fileName)
				{
					this.RemoveAt(i);
					break;
				}
		}

		/// <summary>
		/// Returns the index of the specified file name or -1
		/// </summary>
		/// <param name="fullFileName">The full file name (including path)</param>
		/// <returns></returns>
		public int IndexOfOldName(string fullFileName)
		{
			for (int i = 0; i < this.Count; i++)
			{
				if (this[i].FullFileName == fullFileName) return i;
			}
			return -1;
		}

		public new void Sort()
		{
			this.Sort(this);
			if (this.Session.Order == Order.Desc) this.Reverse();
		}

		#region IComparer<FileToRename> Members

		public int Compare(FileToRename f1, FileToRename f2)
		{
			if (Session.SortBy == FileCompareOptions.LastWriteTime) return DateTime.Compare(f1.FileName.LastWriteTimeUtc, f2.FileName.LastWriteTimeUtc);
			if (Session.SortBy == FileCompareOptions.LastAccessTime) return DateTime.Compare(f1.FileName.LastAccessTimeUtc, f2.FileName.LastAccessTimeUtc);
			if (Session.SortBy == FileCompareOptions.CreateDate) return DateTime.Compare(f1.FileName.CreationTimeUtc, f2.FileName.CreationTimeUtc);
			if (Session.SortBy == FileCompareOptions.Length) return (int) (f1.FileName.Length - f2.FileName.Length);
			if (Session.SortBy == FileCompareOptions.Extension) return String.Compare(f1.FileName.Extension, f2.FileName.Extension);
			return String.Compare(f1.FileName.Name, f2.FileName.Name);
		}

		#endregion
	}

	public class FileToRename
	{
		public FileInfo FileName { get; set; }
		public String FullFileName { get { return FileName.FullName; } set { FileName = new FileInfo(value); } }
		public String ShortFileName { get { return FileName.Name; } set { throw new Exception("tried to write to shortFileName with: " + value); } }

		public FileInfo NewFileName { get; set; }
		public String FullNewFileName { get { return NewFileName.FullName; } set { NewFileName = new FileInfo(value); } }
		public String ShortNewFileName { get { return NewFileName.Name; } set { throw new Exception("tried to write to ShortNewFileName with: " + value); } }

		public Brush BrushStatus { get; set; }

		public FileToRename()
		{
		}

		public FileToRename(String fileName)
		{
			this.FileName = new FileInfo(fileName);
		}

		public FileToRename(FileInfo fileName)
		{
			this.FileName = fileName;
		}
	}
}
